package com.softer.wxzj.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.softer.wxzj.common.entity.CommonResult;
import com.softer.wxzj.common.entity.Page;
import com.softer.wxzj.common.enums.NumStrEnum;
import com.softer.wxzj.common.enums.ShiroResultEnum;
import com.softer.wxzj.common.util.StringUtils;
import com.softer.wxzj.entity.BaseBuildInfo;
import com.softer.wxzj.entity.ZoneCode;
import com.softer.wxzj.mapper.*;
import com.softer.wxzj.service.ZoneCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = {RuntimeException.class, Exception.class})
public class ZoneCodeServiceImpl implements ZoneCodeService {

    @Autowired
    private ZoneCodeMapper zoneCodeMapper;
    @Autowired
    private SysOperatorMapper sysOperatorMapper;
    @Autowired
    private BaseBuildInfoMapper baseBuildInfoMapper;
    @Autowired
    private BaseRegionInfoMapper baseRegionInfoMapper;
    @Autowired
    private BaseModifyDetailMapper baseModifyDetailMapper;

    @Override
    public CommonResult insert(ZoneCode zoneCode) {
        //添加数据之前判断是否已经存在该区域信息 只判断区域编码 不区分等级  区域编码全国唯一
        int zoneCount = zoneCodeMapper.getCount(zoneCode.getZoneCode());
        if (zoneCount > 0) {
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), "区域列表内已有该区域编码");
        }
        int zoneCodeCount = zoneCodeMapper.insert(zoneCode);
        return CommonResult.ResponseResult(zoneCodeCount);
    }

    /**
     * 未使用
     *
     * @param zoneCode
     * @return
     */
    @Override
    public CommonResult update(ZoneCode zoneCode) {
        int zoneCodeCount = zoneCodeMapper.update(zoneCodeMapper);
        return CommonResult.ResponseResult(zoneCodeCount);
    }

    @Override
    public CommonResult delete(String id) {
        return null;
    }

    @Override
    public CommonResult delete(ZoneCode zoneCode) {
        int num = baseRegionInfoMapper.selectZoneCode(zoneCode.getZoneCode());
        if (num > 0) {
            return CommonResult.ResponseResult(0, "区域代码已被使用不能删除");
        }
        num = baseModifyDetailMapper.selectZoneCode(zoneCode.getZoneCode());
        if (num > 0) {
            return CommonResult.ResponseResult(0, "区域代码已被使用不能删除");
        }
        //删除前判断是否是无子项  若是有子项就返回请删除子项 否则就是操作成功/失败
        //在查询子集时根据父级截取特定
        String ids = zoneCode.getId();
        int ZoneGrade = Integer.parseInt(zoneCode.getZonegrade());
        zoneCodeBll(zoneCode);
        //清空对象内没有用的数据 避免出现错误
        zoneCode.setId(null);
        zoneCode.setZoneName("");
        zoneCode.setRemark(null);
        int zoneCodeCount = zoneCodeMapper.getListCount(zoneCode);
        if (zoneCodeCount > 0 && ZoneGrade != 5) {
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), "请先删除该区域以下的区域");
        } else {
            List<BaseBuildInfo> base = baseBuildInfoMapper.getList();
            for (BaseBuildInfo b : base) {
                if (b.getZoneCode().equals(zoneCode)) {
                    return new CommonResult(ShiroResultEnum.FAIL.getCode(), "该区域代码被使用无法删除");
                }
            }
            int deleteCount = zoneCodeMapper.delete(ids);
            return CommonResult.ResponseResult(deleteCount);
        }
    }

    @Override
    public PageInfo<ZoneCode> getList(Page page, ZoneCode zoneCode) {
        //只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询（Select）方法会被分页。
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        //获取查询到的list
        //list 循环截取 返回list
        List<ZoneCode> list = zoneCodeList(zoneCodeMapper.getList(zoneCode));

        PageInfo<ZoneCode> pageInfo = new PageInfo<>(list);
        return pageInfo;
    }

    @Override
    public ZoneCode getInfo(String id) {
        return null;
    }


    /**
     * 获取区域List
     *
     * @param zoneCode
     * @return
     */
    @Override
    public List<ZoneCode> selectList(ZoneCode zoneCode) {
        List<ZoneCode> zoneCodeList = zoneCodeMapper.getAllList();
        List<ZoneCode> firstList = zoneCodeList.stream().filter(p -> NumStrEnum.ONE.getNum().equals(p.getZonegrade())).collect(Collectors.toList());
        for (int i = 0; i < firstList.size(); i++) {
            List<ZoneCode> secondLists = zoneCodeList.stream().filter(p -> NumStrEnum.TWO.getNum().equals(p.getZonegrade())).collect(Collectors.toList());
            String firstZoneCode = firstList.get(i).getZoneCode();
            List<ZoneCode> secondList = secondLists.stream().filter(p -> p.getZoneCode().substring(0, 2).equals(firstZoneCode)).collect(Collectors.toList());
            for (int m = 0; m < secondList.size(); m++) {
                List<ZoneCode> thirdLists = zoneCodeList.stream().filter(p -> NumStrEnum.THREE.getNum().equals(p.getZonegrade())).collect(Collectors.toList());
                String secondZoneCode = secondList.get(m).getZoneCode();
                List<ZoneCode> thirdList = thirdLists.stream().filter(p -> p.getZoneCode().substring(0, 4).equals(secondZoneCode)).collect(Collectors.toList());
                for (int n = 0; n < thirdList.size(); n++) {
                    List<ZoneCode> fourthLists = zoneCodeList.stream().filter(p -> NumStrEnum.FOUR.getNum().equals(p.getZonegrade())).collect(Collectors.toList());
                    String thirdZoneCode = thirdList.get(n).getZoneCode();
                    List<ZoneCode> fourthList = fourthLists.stream().filter(p -> p.getZoneCode().substring(0, 6).equals(thirdZoneCode)).collect(Collectors.toList());
                    for (int t = 0; t < fourthList.size(); t++) {
                        List<ZoneCode> fifthLists = zoneCodeList.stream().filter(p -> NumStrEnum.FIVE.getNum().equals(p.getZonegrade())).collect(Collectors.toList());
                        String fourthZoneCode = fourthList.get(t).getZoneCode();
                        List<ZoneCode> fifthList = fifthLists.stream().filter(p -> p.getZoneCode().substring(0, 9).equals(fourthZoneCode)).collect(Collectors.toList());
                        fourthList.get(t).setList(fifthList);
                    }
                    thirdList.get(n).setList(fourthList);
                }
                secondList.get(m).setList(thirdList);
            }
            firstList.get(i).setList(secondList);
        }
        return firstList;
    }

    /**
     * 根据当前信息  查询ZoneCode 的行数
     *
     * @param zoneCode
     * @return
     */
    @Override
    public int getListCount(ZoneCode zoneCode) {
        return zoneCodeMapper.getListCount(zoneCode);
    }

    /**
     * 传入ZoneCode 根据当前区域等级 和本次区域等级截取字符串 更改model  返回ZoneCode
     * 区域等级为5时 不更改信息
     * 等级+1
     *
     * @param zoneCode
     * @return
     */
    public ZoneCode zoneCodeBll(ZoneCode zoneCode) {
        //在查询子集时根据父级截取特定
        switch (Integer.parseInt(zoneCode.getZonegrade())) {
            case 1:
                //根据省的等级和编码查询市
                zoneCode.setZonegrade(String.valueOf(Integer.parseInt(zoneCode.getZonegrade()) + 1));
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 2));
                break;
            case 2:
                //.....查询区
                zoneCode.setZonegrade(String.valueOf(Integer.parseInt(zoneCode.getZonegrade()) + 1));
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 4));
                break;
            case 3:
                //.....查询镇
                zoneCode.setZonegrade(String.valueOf(Integer.parseInt(zoneCode.getZonegrade()) + 1));
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 6));
                break;
            case 4:
                //.....查询居委会
                zoneCode.setZonegrade(String.valueOf(Integer.parseInt(zoneCode.getZonegrade()) + 1));
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 9));
                break;
            case 5:
                //等级为5时 已经是最后一级 5+1等于6  查询的数据一定为null/空
                zoneCode.setZonegrade(String.valueOf(Integer.parseInt(zoneCode.getZonegrade()) + 1));
                break;
            default:
                //其他等级不做任何操作
                break;
        }
        return zoneCode;
    }


    /**
     * 查询时 根据前端的需求  需要截取本等级的区域编码 区域编码后面多余0排除掉
     *
     * @param zoneCode
     * @return
     */
    public ZoneCode zoneCodeBllSubstring(ZoneCode zoneCode) {
        //在查询子集时根据父级截取特定
        switch (Integer.parseInt(zoneCode.getZonegrade())) {
            case 1:
                //根据省的等级和编码查询市2
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 2));
                break;
            case 2:
                //.....查询区4
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 4));
                break;
            case 3:
                //.....查询镇6
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 6));
                break;
            case 4:
                //.....查询居委会9
                zoneCode.setZoneCode(StringUtils.substring(zoneCode.getZoneCode(), 0, 9));
                break;
            default:
                //其他等级不做任何操作 12
                break;
        }
        return zoneCode;
    }


    /**
     * 循环遍历每个list
     * 根据前端需求 循环截取 当前list
     *
     * @param zoneCodeList
     * @return
     */
    public List<ZoneCode> zoneCodeList(List<ZoneCode> zoneCodeList) {
        List<ZoneCode> zoneCodeListNew = new ArrayList<>();
        //循环遍历每个对象  把每个对象的区域编码按等级截取
        for (int i = 0; i < zoneCodeList.size(); i++) {
            ZoneCode zoneCodeNew = zoneCodeBllSubstring(zoneCodeList.get(i));
            zoneCodeListNew.add(zoneCodeNew);
        }
        return zoneCodeListNew;
    }


    /**
     * 根据区域代码查询区域信息 封装下级
     *
     * @param ZoneCode 区域编码  格式： 12,13,80（这是最高级）
     * @return
     */
    @Override
    public List<ZoneCode> zoneCodeListWhole(String ZoneCode) {
        Map map = new HashMap();
        map.put("zone_code", ZoneCode.split(","));
        List<ZoneCode> zoneCodeList1 = zoneCodeMapper.getListInZoneCode(map);
        forListZone(zoneCodeList1);
        return zoneCodeList1;
    }


    /**
     * 封装多层嵌套list  区域信息
     *
     * @param list（不同级别的区域代码集合）
     * @return
     */
    public void forListZone(List<ZoneCode> list) {

        for (int i = 0; i < list.size(); i++) {
            String ZoneGrade = list.get(i).getZonegrade();
            ZoneCode zoneCodeNew = zoneCodeBll(list.get(i));
            //查询当前区域代码的下一级代码集合
            List<ZoneCode> zoneCodeList = zoneCodeMapper.getListPart(zoneCodeNew);
            //循环调用自己
            forListZone(zoneCodeList);
            list.get(i).setZonegrade(ZoneGrade);
            if (zoneCodeList.size() == 0) {
                list.get(i).setList(null);
            } else {
                list.get(i).setList(zoneCodeList);
            }

        }
    }

    /**
     * 根据区域编码和登陆人查询全部上级
     *
     * @param zoneCode
     * @return
     */
    @Override
    public String zoneCodeSuperiors(String zoneCode, String operNo) {
        String zoneCodeHighest = sysOperatorMapper.getZoneCode(operNo);
        String[] codes = zoneCodeHighest.split(",");
        for (String code : codes) {
            int num = code.length();
            String result = zoneCode.substring(0, num);
            if (result.equals(code)) {
                zoneCodeHighest = code;
            }
        }
        //小区
        String zoneCodeNew = zoneCodeMapper.zoneCodeSuperiors(zoneCodeHighest, zoneCode);
        return zoneCodeNew;
    }

    @Override
    public String getAllZoneCode(String zoneCode) {
        return zoneCodeMapper.getAllZoneCode(zoneCode);
    }

    @Override
    public List<ZoneCode> zoneCodeListWholeOut() {
        List<ZoneCode> zoneCodeList1 = zoneCodeMapper.getListInZoneCodeOut();
        forListZone(zoneCodeList1);
        return zoneCodeList1;
    }

    /**
     * 查询区域名称
     *
     * @param zoneCode 区域代码
     * @return 区域名称
     */
    @Override
    public String getAllZoneName(String zoneCode) {
        return zoneCodeMapper.getAllZoneName(zoneCode);
    }


    /**
     * 根据区域编码查询全部上级
     *
     * @param zoneCode
     * @return
     */
    @Override
    public String zoneCodeSuperiorsAll(String zoneCode) {
        String zoneCodeHighest = zoneCode.substring(0, 2);
        //小区
        String zoneCodeNew = zoneCodeMapper.zoneCodeSuperiors(zoneCodeHighest, zoneCode);
        return zoneCodeNew;
    }

    @Override
    public String zoneName(ZoneCode zoneCode) {
        String newName = "";
        int newGrade = Integer.parseInt(zoneCode.getZonegrade());
        if(newGrade<=3){
            for (int i = 0; i < newGrade; i++) {
                newName = newName + "/" + zoneCodeMapper.selectNameById(zoneCode.getZoneCode().substring(0, i*2+2));
            }
        }
        if (newGrade > 3) {
            for (int i = 0; i < newGrade - 3; i++) {
                newName = newName + "/" + zoneCodeMapper.selectNameById(zoneCode.getZoneCode().substring(0, 6 + i * 3 + 3));
            }
        }
        newName = newName.substring(1);
        return newName;
    }

    /**
     * 根据当前区域编码的长度判断是什么区域等级
     *
     * @param zoneCode
     * @return
     */
    public String zoneCodeBllSubstringGrade(String zoneCode) {
        //在查询子集时根据父级截取特定
        String zoneGrade = NumStrEnum.ZERO.getNum();
        switch (zoneCode.length()) {
            case 2:
                //省的等级
                zoneGrade = NumStrEnum.ONE.getNum();
                break;
            case 4:
                //市的等级
                zoneGrade = NumStrEnum.TWO.getNum();
                break;
            case 6:
                //镇的等级
                zoneGrade = NumStrEnum.THREE.getNum();
                break;
            case 9:
                //街道
                zoneGrade = NumStrEnum.FOUR.getNum();
                break;
            case 12:
                // 居委会
                zoneGrade = NumStrEnum.FIVE.getNum();
                break;
            default:
                //其他等级不做任何操作
                break;
        }
        return zoneGrade;
    }
}
